﻿#region
/* ===============================================
 * 作者：guopeng           时间：2012/2/27 22:12:07
 * 
 * 
 * 类描述：
 * 
 * 
 * =============================================== */
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Documents;
using Lucene.Net.Search;
using Lucene.Net.QueryParsers;
using PanGu;
using ueEngine.Biz.Core.ExServer.WorkPool.WorkHandle.FullSearch;
using ueEngine.Biz.Inf.LogicEntity;
using ueEngine.Framework.Common;

namespace ueEngine.Biz.Core.ExServer.FullSearch.Core
{
    public class PositionIndex : Index<PositionCell>
    {
        public PositionIndex(int maxMergeFactor=301, int minMergeDocs=301)
            : base(maxMergeFactor, minMergeDocs)
        { }
        internal override void IndexString(PositionCell article)
        {
            Document doc = new Document();
            Field field = new Field("RecuritId", article.RecuritId.ToString(), Field.Store.YES, Field.Index.NO);
            doc.Add(field);
            field = new Field("PositionId", article.PositionId.ToString(), Field.Store.YES, Field.Index.NO);
            doc.Add(field);
            field = new Field("Url", article.Url, Field.Store.YES, Field.Index.NO);
            doc.Add(field);
            field = new Field("Agent", article.Recuriter, Field.Store.YES, Field.Index.NOT_ANALYZED);
            doc.Add(field);
            field = new Field("CompanyName", article.CompanyName, Field.Store.YES, Field.Index.NO);
            doc.Add(field);
            field = new Field("Title", article.Title, Field.Store.YES, Field.Index.NO);
            doc.Add(field);
            field = new Field("WorkArea", article.WorkArea, Field.Store.YES, Field.Index.NOT_ANALYZED);
            doc.Add(field);
            field = new Field("PositionType", article.PositionType.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED);
            doc.Add(field);
            field = new Field("CertificationLevel", article.CertificationLevel.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED);
            doc.Add(field);
            field = new Field("Priority", article.Priority.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED);
            doc.Add(field);
            field = new Field("RecruitSheetType", article.RecruitSheetType.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED);
            doc.Add(field);
            field = new Field("RecruitSheetSubject", article.RecruitSheetSubject.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED);
            doc.Add(field); 
            field = new Field("PublishDate", DateTools.DateToString(article.PublishDate,DateTools.Resolution.HOUR), Field.Store.YES, Field.Index.NOT_ANALYZED);
            doc.Add(field);
            field = new Field("Content", article.Content, Field.Store.YES, Field.Index.ANALYZED);
            doc.Add(field);
            base.writer.AddDocument(doc);
            return;
        }

        public override List<PositionCell> Search(string key, RecruitSheetType source,RecruitSheetSubject subject, AreaCode areaCode,PositionType positionType,string agent, int pageLen, int pageNo, out int recCount)
        {
            
            IndexSearcher search = new IndexSearcher(base.INDEX_DIR, true);
            
            string keywords = key;
            key = GetKeyWordsSplitBySpace(key, new PanGuTokenizer());

            BooleanQuery bq = new BooleanQuery();

            QueryParser contentQueryParser = new QueryParser("Content", new PanGuAnalyzer(true));
            Query content = contentQueryParser.Parse(key);
            bq.Add(content, BooleanClause.Occur.MUST);

            if (subject != RecruitSheetSubject.Default)
            {
                QueryParser subjectQueryParser = new QueryParser("RecruitSheetSubject", new PanGuAnalyzer(true));
                Query subjectCode = subjectQueryParser.Parse(((int)subject).ToString());
                bq.Add(subjectCode, BooleanClause.Occur.MUST);
            }

            if (source != RecruitSheetType.NoDefine)
            {
                QueryParser rtQueryParser = new QueryParser("RecruitSheetType", new PanGuAnalyzer(true));
                Query rtCode = rtQueryParser.Parse(((int)source).ToString());
                bq.Add(rtCode, BooleanClause.Occur.MUST);

                if (source == RecruitSheetType.Normal) //最新兼职
                {
                    //添加条件，发布时间为30天之内
                    bq.Add(new TermRangeQuery("PublishDate",
                        DateTools.DateToString(DateTime.Now.AddDays(-30), DateTools.Resolution.DAY),
                        DateTools.DateToString(DateTime.Now, DateTools.Resolution.DAY),
                        true,true), BooleanClause.Occur.MUST);
                    ////添加条件，过期时间为今天之后
                    //bq.Add(new TermRangeQuery("ExpireDate",
                    //    DateTools.DateToString(DateTime.Now, DateTools.Resolution.DAY),
                    //    DateTools.DateToString(DateTime.Now.AddYears(10), DateTools.Resolution.DAY),
                    //    true,true), BooleanClause.Occur.MUST);
                }
            }
            
            if (areaCode != AreaCode.NoDefine)
            {
                QueryParser workAreaQueryParser = new QueryParser("WorkArea", new PanGuAnalyzer(true));
                Query areaCodeQuery = workAreaQueryParser.Parse(areaCode.Mapping());
                bq.Add(areaCodeQuery, BooleanClause.Occur.MUST);
            }
            if (positionType != PositionType.NoDefine)
            {
                QueryParser positionTypeQueryParser = new QueryParser("PositionType", new PanGuAnalyzer(true));
                Query positionTypeQuery = positionTypeQueryParser.Parse(((int)positionType).ToString());
                bq.Add(positionTypeQuery, BooleanClause.Occur.MUST);
            }
            if (!String.IsNullOrEmpty(agent))
            {
                Query agentQuery = new TermQuery(new Lucene.Net.Index.Term("Agent", agent));
                bq.Add(agentQuery, BooleanClause.Occur.MUST);
            }
            Hits hits = search.Search(bq);

            return FormatResult(pageLen, pageNo, search, key, hits, out recCount);
        }
        
        private static List<PositionCell> FormatResult(int pageLen, int pageNo, IndexSearcher search, string keywords, Hits hits, out int recCount)
        {
            List<PositionCell> result = new List<PositionCell>();
            recCount = hits.Length();
            int i = (pageNo - 1) * pageLen;
            while (i < recCount && result.Count < pageLen)
            {
                PositionCell position = null;
                try
                {
                    position = new PositionCell()
                    {
                        RecuritId = hits.Doc(i).Get("RecuritId").ToInt32(0),
                        PositionId = hits.Doc(i).Get("PositionId").ToInt32(0),
                        Url = hits.Doc(i).Get("Url"),
                        CompanyName = hits.Doc(i).Get("CompanyName"),
                        Title = hits.Doc(i).Get("Title"),
                        WorkArea = hits.Doc(i).Get("WorkArea"),
                        PositionType = hits.Doc(i).Get("PositionType").ToInt32(0),
                        CertificationLevel =hits.Doc(i).Get("CertificationLevel").ToInt32(0),
                        //PositionLevel = hits.Doc(i).Get("PositionLevel").ToInt32(0),
                        Priority = hits.Doc(i).Get("Priority").ToInt32(0),
                        PublishDate = DateTools.StringToDate(hits.Doc(i).Get("PublishDate")),
                        Content = hits.Doc(i).Get("Content"),
                        RecruitSheetType = hits.Doc(i).Get("RecruitSheetType").ToInt32(0),
                        RecruitSheetSubject = hits.Doc(i).Get("RecruitSheetSubject").ToInt32(0)
                    };
                    PanGu.HighLight.SimpleHTMLFormatter simpleHTMLFormatter =
                        new PanGu.HighLight.SimpleHTMLFormatter("<font color=\"red\">", "</font>");

                    PanGu.HighLight.Highlighter highlighter =
                        new PanGu.HighLight.Highlighter(simpleHTMLFormatter,
                        new Segment());

                    highlighter.FragmentSize = 50;

                    position.Abstract = highlighter.GetBestFragment(keywords, position.Content);
                    position.TitleHighLighter = highlighter.GetBestFragment(keywords, position.Title);
                    if (string.IsNullOrEmpty(position.TitleHighLighter))
                    {
                        position.TitleHighLighter = position.Title;
                    }

                }
                catch (Exception e)
                {
                    LogHelper.Write(CommonLogger.ExServer, LogLevel.Error, e);
                }
                finally
                {
                    result.Add(position);
                    i++;
                }
            }

            search.Close();
            return result;
        }
    }
}
